#ifndef _FASTSET_HH_
#define _FASTSET_HH_
#include <cassert>
#include <cstring>
#include <limits>
#include <cstdlib>


/// Fast Set of unsigned integers
template<typename MType = unsigned>
struct FastSet
{
  unsigned size;
  MType * marks;
  MType mark;

  /// Class builder
  FastSet(void) :
    marks(NULL),mark(0) {}


  /// Class destructor
  ~FastSet(void)
  {
    if(marks!=NULL)
      {
	delete [] marks;
      }
  }


  /// Init
  void init(unsigned _size)
  {
    assert(marks==NULL);
    size = _size;
    marks = new MType[size];
    memset(marks,0,size*sizeof(MType));
    mark = 0;
  }


  /// 'Clear' the set for a new usage
  void reset(void)
  {
    assert(marks!=NULL);
    if(mark!=std::numeric_limits<MType>::max())
      mark++;
    else
      {
	memset(marks,0,size*sizeof(MType));
	mark = 1;
      }
  }


  inline void insert(unsigned val)
  {
    assert(val<size);
    marks[val] = mark;
  }

  inline bool count(unsigned val)
  {
    assert(val<size);
    return (marks[val] == mark);
  }

};



#endif /* _FASTSET_HH_ */
